<?php

class FP_Application_Bootstrap {

    protected static $_instance = null;
    protected static $_staging_environment = STAGING_PRODUCTION;

    protected static $_custom_subsystems = array();
    protected static $_router = null;

    protected static function &GetInstance(){
	if (self::$_instance === null)
	    self::$_instance = new FP_Application_Bootstrap(self::$_staging_environment);
	return self::$_instance;
    }

    public static function RegisterSubsystem($pName, $pPrefix, $pConfig=null){
	self::$_custom_subsystems[] = array('name' => $pName, 'prefix' => $pPrefix, 'config' => $pConfig);
    }

    public static function RegisterRouter(Zend_Controller_Router_Interface $pRouter){
	self::$_router = $pRouter;
    }

    public static function Start(){
	Zend_Controller_Front::run(realpath(BASE_DIR . 'app/controllers'));
    }

    public static function Setup($pStagingEnvironment=STAGING_PRODUCTION){
	self::$_staging_environment = $pStagingEnvironment;

	$bs =& self::getInstance();

	$bs->initInternalCache();
	$bs->loadConfig();

	$bs->preInit();

	$bs->loadSubsystems();
 	$bs->loadCustomSubsystems(self::$_custom_subsystems);

	$bs->loadRoutes();

	$bs->postInit();

    }

    public static function GetStagingEnvironment(){
	return self::$_staging_environment;
    }

    /* INTERNAL */

    protected $_config = null;
    protected $_cache = null;
    protected $_subsystems = null;

    protected function __construct(){
	$this->_subsystems = array();
    }

    protected function initInternalCache(){
	$this->_cache = Zend_Cache::factory('Core', 'File', array('lifetime' => 900, 'automatic_serialization' => true), array('cache_dir' => $_SERVER['DOCUMENT_ROOT'] . '/cache/'));
    }

    protected function loadConfig(){
	$this->_config = new Zend_Config_Ini(realpath(BASE_DIR . 'config/config.ini'), strtolower(self::$_staging_environment));

	FP_Application::Set('config', $this->_config);
    }

    protected function preInit(){
	ini_set('display_errors', $this->_config->system->php->display_errors);
	ini_set('display_startup_errors', $this->_config->system->php->display_startup_errors);

 	$config = FP_Application::get('config');

	if (self::$_router)
	    Zend_Controller_Front::getInstance()->setRouter(self::$_router);
 	else
 	    Zend_Controller_Front::getInstance()->setRouter(new Zend_Controller_Router_Rewrite());

	if (isset($config->error->throw_exceptions))
	    Zend_Controller_Front::getInstance()->throwExceptions($config->error->throw_exceptions);

	if (isset($config->application->outputBuffering))
	    Zend_Controller_Front::getInstance()->setParam('disableOutputBuffering', !$config->application->outputBuffering);

	if (isset($config->application->baseUrl))
	    Zend_Controller_Front::getInstance()->setBaseUrl($config->application->baseUrl);

	$baseUrl = rtrim(Zend_Controller_Front::getInstance()->getBaseUrl(), '/');
	$docroot = rtrim($_SERVER['DOCUMENT_ROOT'], '/');

	FP_Application::Set('baseUrl', $baseUrl);
	FP_Application::Set('docroot', $docroot);
	FP_Application::Set('server', ((array_key_exists('HTTPS', $_SERVER) && $_SERVER['HTTPS']) ? 'https://' : 'http://') . $_SERVER['SERVER_NAME']);
	FP_Application::Set('assets', "$baseUrl/assets");
	FP_Application::Set('cachedir', BASE_DIR . 'public/cache');
	FP_Application::Set('uploads', "$baseUrl/uploads");
	FP_Application::Set('uploadsdir', "$docroot/uploads");
    }

    protected function loadSubsystems(){

	$this->_subsystems['session'] = FP_Application_Subsystem::Factory('session', $this->_config->session);
	$this->_subsystems['logger'] = FP_Application_Subsystem::Factory('logger', $this->_config->logger);
	$this->_subsystems['cache'] = FP_Application_Subsystem::Factory('cache', $this->_config->cache);
	$this->_subsystems['database'] = FP_Application_Subsystem::Factory('database', $this->_config->database);
	$this->_subsystems['locale'] = FP_Application_Subsystem::Factory('locale', $this->_config->locale);
	$this->_subsystems['mail'] = FP_Application_Subsystem::Factory('mail', $this->_config->mail);
	$this->_subsystems['view'] = FP_Application_Subsystem::Factory('view', $this->_config->view);
	$this->_subsystems['acl'] = FP_Application_Subsystem::Factory('acl', $this->_config->acl);

    }

    protected function loadCustomSubsystems($pSubsystems){
	foreach ($pSubsystems as $subsystem){
	    logdebug("FP_Application_Bootstrap.loadCustomSubsystems: Loading {$subsystem['name']}");
	    $this->_subsystems[$subsystem['name']] = FP_Application_Subsystem::Factory($subsystem['name'], $subsystem['config'], $subsystem['prefix']);
	}
    }

    protected function loadRoutes(){
	$routes = array();
	include(BASE_DIR . 'config/routes.php');
	Zend_Controller_Front::getInstance()->getRouter()->addRoutes($routes);
    }

    protected function postInit(){
	Zend_Controller_Front::getInstance()->throwExceptions(false);
	Zend_Controller_Front::getInstance()->registerPlugin(new FP_Controller_Plugin_ErrorHandler(), 50);

	Zend_Controller_Action_HelperBroker::addHelper(new FP_Controller_Action_Helper_Referer());
    }

}

?>